package cn.iocoder.yudao.module.vote.controller.app.voteonline;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.vote.aop.SubmitCheck;
import cn.iocoder.yudao.module.vote.constants.RedisConst;
import cn.iocoder.yudao.module.vote.constants.VotePersonTypeEnum;
import cn.iocoder.yudao.module.vote.controller.admin.dept.vo.VoteDeptExportReqVO;
import cn.iocoder.yudao.module.vote.controller.admin.dept.vo.VoteDeptRespVO;
import cn.iocoder.yudao.module.vote.controller.admin.voteinfo.vo.OnlineVoteParamsVO;
import cn.iocoder.yudao.module.vote.controller.admin.voteinfo.vo.VoteInfoRespVO;
import cn.iocoder.yudao.module.vote.controller.admin.voterecorddetail.vo.VoteRecordDetailExportReqVO;
import cn.iocoder.yudao.module.vote.controller.admin.voteuserresult.vo.VoteOnlineUpdateReqVO;
import cn.iocoder.yudao.module.vote.controller.admin.voteuserresult.vo.VoteYearUserResultDeptRespVO;
import cn.iocoder.yudao.module.vote.controller.admin.voteuserresult.vo.VoteYearUserResultGroupRespVO;
import cn.iocoder.yudao.module.vote.convert.dept.VoteDeptConvert;
import cn.iocoder.yudao.module.vote.convert.voteinfo.VoteInfoConvert;
import cn.iocoder.yudao.module.vote.dal.dataobject.dept.VoteDeptDO;
import cn.iocoder.yudao.module.vote.dal.dataobject.voteinfo.VoteInfoDO;
import cn.iocoder.yudao.module.vote.dal.dataobject.voterecorddetail.VoteRecordDetailDO;
import cn.iocoder.yudao.module.vote.service.dept.VoteDeptService;
import cn.iocoder.yudao.module.vote.service.voteinfo.VoteInfoService;
import cn.iocoder.yudao.module.vote.service.voterecord.VoteRecordService;
import cn.iocoder.yudao.module.vote.service.voterecorddetail.VoteRecordDetailService;
import cn.iocoder.yudao.module.vote.service.voteuserresult.VoteUserResultService;
import cn.iocoder.yudao.module.vote.utils.AesUtil;
import cn.iocoder.yudao.module.vote.utils.RedisService;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.module.vote.enums.ErrorCodeConstants.*;

@Api(tags = "管理后台 - 年度投票结果")
@RestController
@RequestMapping("/voteyear/online")
@Validated
public class VoteYearOnlineController {

    @Resource
    private VoteUserResultService userResultService;
    @Resource
    private VoteInfoService voteInfoService;
    @Resource
    private VoteRecordService voteRecordService;
    @Resource
    private VoteRecordDetailService detailService;
    @Resource
    private RedisService redisService;

    @Resource
    private VoteDeptService voteDeptService;


    @GetMapping("/getDeptList")
    @ApiOperation("获得部门信息列表")
//    @PreAuthorize("@ss.hasPermission('vote:dept:query')")
    public CommonResult<List<VoteDeptRespVO>> getDeptList(String data) {

        OnlineVoteParamsVO paramsVO = JSONObject.parseObject(AesUtil.decrypt(data), OnlineVoteParamsVO.class);
        if (VotePersonTypeEnum.PARTY_LEADER.getValue().equals(paramsVO.getVotePersonType())||
            VotePersonTypeEnum.OTHER_LEADERS.getValue().equals(paramsVO.getVotePersonType())) {
            return error(NOT_NEED_SELECTED_DEPT);
        }

        VoteDeptExportReqVO exportReqVO = new VoteDeptExportReqVO();
        exportReqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
        List<VoteDeptDO> list = voteDeptService.getDeptList(exportReqVO);
        return success(VoteDeptConvert.INSTANCE.convertList(list));
    }

    @SubmitCheck(value="submitVoteyearOnlineResult")
    @PostMapping("/updateResult")
    @ApiOperation("更新投票结果")
    public CommonResult<Boolean> updateH5Result(@Valid @RequestBody VoteOnlineUpdateReqVO onlineUpdateReqVO,HttpServletRequest request) {
        try {
            OnlineVoteParamsVO paramsVO = JSONObject.parseObject(AesUtil.decrypt(onlineUpdateReqVO.getData()), OnlineVoteParamsVO.class);
            onlineUpdateReqVO.setVotePersonType(paramsVO.getVotePersonType());
            onlineUpdateReqVO.setVoteId(paramsVO.getVoteId());
            String ip = ServletUtil.getClientIP(request, null);
            onlineUpdateReqVO.setIp(ip);

            // 去重，防止重复提交
            List<VoteOnlineUpdateReqVO.VoteStatus> topicList= onlineUpdateReqVO.getVoteStatusList();
            topicList = topicList.stream().distinct().collect(Collectors.toList());
            onlineUpdateReqVO.setVoteStatusList(topicList);



            userResultService.updateOnlineResult(onlineUpdateReqVO);
            return success(true);
        }catch (Exception e){
            if(e instanceof ServiceException){
                throw e;
            }
            exception(ONLINE_ENCRYPT_PARAMS_ERROR);
        }
        return error(ONLINE_ENCRYPT_PARAMS_ERROR);
    }


    @GetMapping("/list")
    @ApiOperation("获得投票结果列表")
    public CommonResult<List<VoteYearUserResultDeptRespVO>> getUserResultList(@RequestParam String data,Long deptId, HttpServletRequest request) {

        try{
            OnlineVoteParamsVO paramsVO = JSONObject.parseObject(AesUtil.decrypt(data),OnlineVoteParamsVO.class);

            VoteInfoDO voteInfoDO = redisService.getCacheObject(StrUtil.format(RedisConst.VOTE_INFO,paramsVO.getVoteId()));
            if(voteInfoDO==null){
                voteInfoDO = voteInfoService.getInfo(paramsVO.getVoteId());
            }
            String ip = ServletUtil.getClientIP(request, null);
            if(voteInfoDO==null){
                throw new ServiceException(INFO_NOT_EXISTS);
            }
            if(!voteInfoDO.getIsPush()){
                throw new ServiceException(INFO_TIME_NOTSTART);
            }
            if (voteRecordService.isVote(voteInfoDO.getId(), ip)) {
                throw new ServiceException(INFO_USER_HAS_VOTED);
            }
            List<VoteYearUserResultDeptRespVO> list = userResultService.getH5VoteList(paramsVO,deptId);
            return success(list);
        }catch (Exception e){
            return error(ONLINE_ENCRYPT_PARAMS_ERROR);
        }
    }



    @PostMapping("/votedList")
    @ApiOperation("获得投票结果列表")
    public CommonResult<List<VoteYearUserResultDeptRespVO>> votedList(@RequestBody VoteRecordDetailExportReqVO reqVO, @RequestParam String data, HttpServletRequest request) {

        OnlineVoteParamsVO paramsVO = JSONObject.parseObject(AesUtil.decrypt(data),OnlineVoteParamsVO.class);
        VoteInfoDO voteInfoDO =voteInfoService.getInfo(paramsVO.getVoteId());
        if(voteInfoDO==null){
            throw new ServiceException(INFO_NOT_EXISTS);
        }
        String ip = ServletUtil.getClientIP(request, null);
        List<VoteYearUserResultDeptRespVO> list = userResultService.getH5UserVotedList(paramsVO,ip);


        return success(list);
    }

    @GetMapping("/voteInfo")
    @ApiOperation("投票规则信息")
    public CommonResult<VoteInfoRespVO> voteInfo(@RequestParam("data")String data) {
            OnlineVoteParamsVO paramsVO = JSONObject.parseObject(AesUtil.decrypt(data),OnlineVoteParamsVO.class);

            VoteInfoDO voteInfoDO = redisService.getCacheObject(StrUtil.format(RedisConst.VOTE_INFO,paramsVO.getVoteId()));
            if(voteInfoDO==null){
                voteInfoDO = voteInfoService.getInfo(paramsVO.getVoteId());
            }
            if(voteInfoDO==null){
                throw new ServiceException(INFO_NOT_EXISTS);
            }
            if(!voteInfoDO.getIsPush()){
                throw new ServiceException(INFO_TIME_NOTSTART);
            }
            if (new Date().after(voteInfoDO.getEndTime())) {
                throw new ServiceException(INFO_TIME_END);
            }
            if (new Date().before(voteInfoDO.getBeginTime())) {
                throw new ServiceException(INFO_TIME_NOTSTART);
            }

            return success(VoteInfoConvert.INSTANCE.convert(voteInfoDO));

    }

    @GetMapping("/userIsVote")
    @ApiOperation("是否已投票")
    public CommonResult<Boolean> userIsVote(@RequestParam("data")String data,HttpServletRequest request) {
        try{
            OnlineVoteParamsVO paramsVO = JSONObject.parseObject(AesUtil.decrypt(data),OnlineVoteParamsVO.class);

            String ip = ServletUtil.getClientIP(request, null);
            return success(voteRecordService.isVote(paramsVO.getVoteId(),ip));
        }catch (Exception e){
            return error(ONLINE_ENCRYPT_PARAMS_ERROR);
        }
//        return success(false);
    }


    @GetMapping("/ping")
    @ApiOperation("是否在内网")
    public CommonResult<Boolean> ping() {
        return success(true);
    }

    public static void main(String[] args) {
        String data = "4950D4DC2AF93A846449BD1B0C2BD0342B18308A6BA50851E3AC33610A4D40BCC922783A0DF071662DE564F6AFA50F32";
        OnlineVoteParamsVO paramsVO = JSONObject.parseObject(AesUtil.decrypt(data),OnlineVoteParamsVO.class);
        System.out.println(JSONObject.toJSONString(paramsVO));
        System.out.println(JSONObject.toJSONString(paramsVO));
    }

}
